#
# Copyright (c) 2023 supercell
#
# SPDX-License-Identifier: BSD-3-Clause
#

module Luce
  # Parses preformatted code blocks that are indented by four spaces.
  class CodeBlockSyntax < BlockSyntax
    def pattern : Regex
      Luce.indent_pattern
    end

    def can_end_block?(parser : BlockParser) : Bool
      false
    end

    def parse_child_lines(parser : BlockParser) : Array(Line)
      child_lines = [] of Line

      until parser.done?
        is_blank_line = parser.current.is_blank_line?
        break if is_blank_line && should_end?(parser)
        break if !is_blank_line && !child_lines.empty? && !pattern.matches?(parser.current.content)

        child_lines << Line.new(
          Luce.dedent_string(parser.current.content).text,
          tab_remaining: parser.current.tab_remaining
        )
        parser.advance
      end

      child_lines
    end

    def parse(parser : BlockParser) : Node
      child_lines = parse_child_lines(parser).compact_map { |e| e }

      # The Markdown tests expect a trailing newline
      child_lines << Line.new("")

      content = child_lines.map { |line| " " * (line.tab_remaining || 0) + line.content }.join("\n")
      content = Luce.escape_html(content, escape_apos: false) if parser.document.encode_html?

      Element.new("pre", [Element.text("code", content)] of Node)
    end

    private def should_end?(parser : BlockParser) : Bool
      i = 1
      loop do
        next_line = parser.peek(i)
        return true if next_line.nil?

        if next_line.is_blank_line?
          i += 1
          next
        end

        return !pattern.matches?(next_line.content)
      end
    end
  end
end
